package mqttClient

import (
	"context"
	"encoding/json"
	"gitee.com/yuyuaa/wensGoMqtt.git/common"
	"log"
	"net"
	"strconv"
	"strings"
)

var MaptcpBridgePool map[string](context.CancelFunc) //一个连接对应sessionid有一个上下文

func (self *Client) setupTcpBridge() {
	//监听连接请求的地址
	topic := self.Config.Mqtt.TcpBridgeCtrl
	clientId, _, _ := self.GetConnectInfoByUid()
	tcplisten := strings.Replace(topic, "{{clientId}}", clientId, -1)
	log.Println("mqtt监听ssh连接请求,topic:", tcplisten)
	MaptcpBridgePool = make(map[string](context.CancelFunc)) //初始化连接的管理池
	self.Base.MqttSub(tcplisten, func(topic string, js []byte) {
		log.Println(topic, string(js))
		linkReq := new(common.TcpLinkControl)
		err := json.Unmarshal(js, linkReq)
		if err != nil {
			log.Println("tcp 连接请求json格式错误", err)
		}
		//连接请求发过来的json为
		log.Println("mqtt收到tcp连接请求", string(topic), linkReq)
		//如果是需要建立连接的话
		if linkReq.Type == common.Const_TcpBridge_Establish {
			ctx, cancel := context.WithCancel(context.Background())
			MaptcpBridgePool[linkReq.SessionId] = cancel
			go self.tcpLinkHandle(ctx, cancel, linkReq)
		}
		//如果是删除连接
		if linkReq.Type == common.Const_TcpBridge_Close {
			log.Println("需要关闭连接,sessionid:", linkReq.SessionId)
			MaptcpBridgePool[linkReq.SessionId]() //执行cancel方法
			delete(MaptcpBridgePool, linkReq.SessionId)
		}
	})
}

func (self *Client) tcpLinkHandle(ctx context.Context, cancel context.CancelFunc, request *common.TcpLinkControl) {
	clientId, _, _ := self.GetConnectInfoByUid()
	tcpSub := strings.Replace(self.Config.Mqtt.TcpSub, "{{clientId}}", clientId, -1)
	//替换sessionId
	readTopic := strings.Replace(tcpSub, "{{sessionId}}", request.SessionId, -1)
	writeTopic := readTopic + self.Config.Mqtt.RespTail //+"/respose"
	log.Println("端口", request.LinkPort, "发送到,topic:", writeTopic)
	log.Println("端口", request.LinkPort, "从:", readTopic, "接收")
	ip := "127.0.0.1:" + strconv.Itoa(request.LinkPort) //127.0.0.1:22
	var dconn net.Conn
	var err error
	//ExitChan := make(chan bool, 1)

	//试着建立连接
	dconn, err = net.Dial("tcp", ip)
	if err != nil {
		log.Printf("连接%v失败:%v\n", ip, err)
		//向请求连接方法发送错误提示
		self.Base.MqttPub(writeTopic, []byte("error:"+err.Error()))
		return
	} else {
		//接收到中心消息
		self.Base.MqttSub(readTopic, func(topic string, msg []byte) {
			log.Println("接收到", string(msg))
			dconn.Write(msg)
		})
		//发送成功，这时远方才正式建立连接
		self.Base.MqttPub(writeTopic, []byte(common.Const_tcpHasEstablish))

		//发送消息
		go func() {
			for {
				b := make([]byte, 1024)
				n, err := dconn.Read(b)
				if err != nil {
					cancel()
					log.Println("错误:", err)
					return
				} else {
					sb := make([]byte, n)
					copy(sb, b)
					self.Base.MqttPub(writeTopic, sb)
					log.Println("发送：", string(sb))
				}

			}
			cancel()
		}()
	}

	<-ctx.Done()
	log.Println("关闭连接xxx")
	dconn.Close()
}

//import (
//	"fmt"
//	"net"
//	"strings"
//	"wens.com/wlw_environment/controller/src/common"
//)
//
//var sshConn net.Conn
//
//type mqttConn struct {
//	ReadTopic  string
//	WriteTopic string
//}
//
////监听一个topic,调用restful api
//func ssh_listen() {

//}
//
//func handle(listenId string) {
//	sshsub := common.MyConfig.Mqtt.SshSub //类似"/wens/wlw/env/ctrl/{{devId}}/api/#"
//	//将{{devId}}替换成mac地址
//	clientId, _, _ := common.GetConnectInfoByUid()
//	sshsub = strings.Replace(sshsub, "{{clientId}}", clientId, -1)
//	mqttc := &mqttConn{}
//	mqttc.WriteTopic = sshsub + listenId + "/respone"
//	mqttc.ReadTopic = sshsub + listenId
//	common.Logger.Debug("端口22发送到,topic:", mqttc.WriteTopic)
//	common.Logger.Debug("端口22从:", mqttc.ReadTopic, "接收")
//
//	//defer mqttt.Close()
//	ip := "127.0.0.1:22"
//
//	var dconn net.Conn
//	var err error
//	ExitChan := make(chan bool, 1)
//
//	//试着建立连接
//	dconn, err = net.Dial("tcp", ip)
//	if err != nil {
//		fmt.Printf("连接%v失败:%v\n", ip, err)
//		//向请求连接方法发送错误提示
//		common.MqttPub(mqttc.WriteTopic, []byte("error:"+err.Error()))
//		return
//	} else {
//
//		//接收到消息
//		common.MqttSub([]string{mqttc.ReadTopic}, func(topic, msg []byte) {
//			common.Logger.Debug("接收到", string(msg))
//			dconn.Write(msg)
//		})
//		//发送成功，这时远方才正式建立连接
//		common.MqttPub(mqttc.WriteTopic, []byte("success"))
//
//		//发送消息
//		go func() {
//			for {
//				b := make([]byte, 1024)
//				n, err := dconn.Read(b)
//				if err != nil {
//					ExitChan <- true
//					common.Logger.Debug(err)
//					return
//				} else {
//					sb := make([]byte, n)
//					copy(sb, b)
//					common.MqttPub(mqttc.WriteTopic, sb)
//					common.Logger.Debug("发送：", string(sb))
//				}
//
//			}
//			ExitChan <- true
//		}()
//	}
//
//	<-ExitChan
//	dconn.Close()
//}
